package org.akomantoso.core.io.util.group;

import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.StringItem;
import org.akomantoso.core.data.group.InlineCM;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;
import org.akomantoso.core.io.util.Instantiator;
import org.akomantoso.core.util.MapUtil;
import org.akomantoso.core.util.StringUtil;

/**
 * @author <a href="mailto:jacques.militello@gmail.com">Jacques Militello</a>
 */
public class InlineCMGroup {

	private InlineCMGroup() {
	}

	public static final Map<String, Instantiator<InlineCM>> MAP;

	static {
		Map<String, Instantiator<InlineCM>> temp = new IdentityHashMap<String, Instantiator<InlineCM>>();
		MapUtil.copy(InlineElementsGroup.MAP, temp);
		MapUtil.copy(PopupElementsGroup.MAP, temp);
		MapUtil.copy(MarkerElementsGroup.MAP, temp);
		MAP = temp;
	}

	public static void read(Input in, List<InlineCM> elements) throws IOException {
		InlineCM inlineCM = null;
		final String localName = in.getLocalName();

		int eventType;
		while (true) {
			eventType = in.readNext();
			switch (eventType) {
			case InputConstants.START_ELEMENT:
				elements.add(inlineCM = instantiate(in.getLocalName()));
				inlineCM.readExternal(in);
				break;
			case InputConstants.CHARACTERS:
				String tempString = in.readContent();
				if (!in.isWhiteSpace()) {
					elements.add(new StringItem(StringUtil.deleteAnyControlChar(tempString)));
				}
				break;
			case InputConstants.END_ELEMENT:
				if (localName == in.getLocalName()) {
					return;
				}
			}
		}
	}

	private static InlineCM instantiate(String element) {
		final Instantiator<InlineCM> instatiator = MAP.get(element);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + element + "] not supported InlineCM ?!?");
		}
		return instatiator.instantiate();
	}

}